import { _decorator, Component, Size, tween, Tween, UITransform, v3, Vec2, Vec3 } from 'cc';
import { Ab_Tile_bA } from '../../ui/tile';
const { ccclass, property } = _decorator;

@ccclass('Ab_GameDrawer_bA')
export class Ab_GameDrawer_bA extends Component {

	protected Ab_uitrans_bA: UITransform;

	/** 抽屉的容量 */
	protected Ab_capacity_bA: number;
	/** 基准线高度 */
	protected Ab_base_height_bA: number;
	/** 抽屉中的砖块尺寸 */
	protected Ab_tile_size_bA: Size;
	/** 容器的左边界 */
	protected Ab_left_board_bA: number;
	/** 砖块之间的间距 */
	protected Ab_padding_x_bA: number = 0;
	/** tween动画的速度 */
	protected Ab_tween_speed_bA: number;

	/** 正在添加到抽屉中的砖块(动画中) */
	protected Ab_adding_tile_bA: {token: string, np: abi.Ab_NudityPromise_bA<string>}[] = [];
	/** 当前容器内的砖块数据 */
	protected Ab_record_list_bA: {tier: number, coor: Vec2, tile: Ab_Tile_bA, token?: string}[] = [];
	/** 当前容器内的砖块 */
	protected Ab_tile_list_bA: Ab_Tile_bA[] = [];

	/** 剩余空间 */
	public get Ab_residue_bA(){
		return this.Ab_capacity_bA - this.Ab_record_list_bA.length;
	}

	public get Ab_tileCount_bA(){
		return this.Ab_tile_list_bA.length;
	}

	protected onLoad(){
		this.Ab_uitrans_bA = this.node.getComponent(UITransform);
		this.Ab_record_list_bA = [];
		this.Ab_adding_tile_bA = [];
		this.Ab_tile_list_bA = [];
	}

    protected start(){
		this.Ab_left_board_bA = -this.Ab_uitrans_bA.width * this.Ab_uitrans_bA.anchorX;

		this.Ab_tile_size_bA = Ab_Tile_bA.Ab_calculateSizeByBackground_bA(this.Ab_uitrans_bA.width / this.Ab_capacity_bA, this.Ab_uitrans_bA.height).block;
		this.Ab_padding_x_bA = (this.Ab_uitrans_bA.width - this.Ab_tile_size_bA.width * this.Ab_capacity_bA) / (this.Ab_capacity_bA + 1);
		this.Ab_tween_speed_bA = Math.max(this.Ab_tile_size_bA.width, this.Ab_tile_size_bA.height) / 0.1;
    }

	protected Ab_recordToken_bA(record: typeof this.Ab_record_list_bA[number]){
		record.token = [
			['id', record.tile.Ab_ID_bA],
			['tier', record.tier],
			['x', record.coor.x],
			['y', record.coor.y]
		].map(el=>el.join(':')).join('; ');

		return record.token;
	}

	protected Ab_getPostionByIndex_bA(index: number, out?: Vec3){
		let x = this.Ab_left_board_bA + this.Ab_tile_size_bA.width * (index + 0.5) + this.Ab_padding_x_bA * (index+1);
		let y = this.Ab_base_height_bA - (this.Ab_uitrans_bA.anchorY - 0.5) * this.Ab_uitrans_bA.height;
		if(out) out.set(x, y);
		else out = v3(x, y);

		return out;
	}

	protected Ab_getNext_bA(tile: Ab_Tile_bA, out?: Vec3){
		if(!this.Ab_base_height_bA){
			this.Ab_base_height_bA = -tile.Ab_getBackgroundPosition_bA(this.Ab_tile_size_bA).y;
			this.Ab_base_height_bA = abi.Ab_number_bA.Ab_fixedNum_bA(this.Ab_base_height_bA, 4);
		}
		let index = this.Ab_record_list_bA.length;
		return {index, position: this.Ab_getPostionByIndex_bA(index, out)};
	}

	private Ab_refresh_distance_bA = v3();
	protected Ab_refresh_bA(){
		let np = new abi.Ab_NudityPromise_bA<'end'>();

		let duration = 0;

		let distance = 0;
		let time = 0;
		this.Ab_tile_list_bA.forEach((tile, index)=>{
			let token = this.Ab_record_list_bA.find(el=>el.tile==tile).token;
			if(this.Ab_adding_tile_bA.find(el=>el.token==token)) return void 0;

			let position = this.Ab_getPostionByIndex_bA(index);
			distance = Vec3.subtract(this.Ab_refresh_distance_bA, tile.node.position, position).length();
			distance = Math.round(distance * 10000) / 10000;

			if(!(distance>0)) return void 0;

			time = distance / this.Ab_tween_speed_bA;
			if(time > duration) duration = time;

			Tween.stopAllByTarget(tile.node);
			tween(tile.node).to(time, {position}, {easing: 'cubicOut'}).set({position}).start();
		});

		this.scheduleOnce(()=>np.Ab_resolve_bA('end'), duration + 0.1);
		return np.Ab_promise_bA;
	}

	protected Ab_removeRecordByTile_bA(tile: Ab_Tile_bA){
		let record = abi.Ab_array_bA.Ab_remove_bA(this.Ab_record_list_bA, el=>el.tile==tile);
		if(record){
			abi.Ab_array_bA.Ab_remove_bA(this.Ab_tile_list_bA, tile);
			abi.Ab_array_bA.Ab_remove_bA(this.Ab_adding_tile_bA, el=>el.token==record.token);
		}

		return record;
	}

	protected Ab_afterPadded_bA(record: typeof this.Ab_record_list_bA[number]){

	}

	public Ab_padding_bA(record: {tier: number, coor: Vec2, tile: Ab_Tile_bA}, world_position?: Vec3){
		let next = this.Ab_getNext_bA(record.tile);
		let token = this.Ab_recordToken_bA(record);
		if(this.Ab_record_list_bA.find(el=>el.token==token)) return void 0;

		let np = new abi.Ab_NudityPromise_bA<string>();
		this.Ab_adding_tile_bA.push({token, np});
		this.Ab_record_list_bA.push(record);
		this.Ab_tile_list_bA.splice(next.index, 0, record.tile);
		if(world_position) this.Ab_uitrans_bA.convertToWorldSpaceAR(next.position, world_position);
		else world_position = this.Ab_uitrans_bA.convertToWorldSpaceAR(next.position);
		record.tile.Ab_setSize_bA(this.Ab_tile_size_bA);
		this.Ab_refresh_bA();
		return {
			token,
			world_position,
			promise: np.Ab_promise_bA,
		};
	}

	public Ab_padded_bA(token: string){
		let info = abi.Ab_array_bA.Ab_remove_bA(this.Ab_adding_tile_bA, el=>el.token==token);
		if(info){
			info.np.Ab_resolve_bA(token);
		}

		let record = this.Ab_record_list_bA.find(el=>el.token==token);
		if(record){
			let position = this.Ab_uitrans_bA.convertToNodeSpaceAR(record.tile.node.worldPosition);
			record.tile.node.removeFromParent();
			record.tile.node.setParent(this.node);
			record.tile.node.setPosition(position);
		}

		this.Ab_afterPadded_bA(record);
	}

	private Ab_clean_call_list_bA: Array<(list: Ab_Tile_bA[])=>void> = [];
	public Ab_clean_bA(){
		abi.Ab_array_bA.Ab_clear_bA(this.Ab_adding_tile_bA);
		abi.Ab_array_bA.Ab_clear_bA(this.Ab_record_list_bA);
		let tile_list = abi.Ab_array_bA.Ab_clear_bA(this.Ab_tile_list_bA);
		this.Ab_clean_call_list_bA.forEach(fn=>fn(tile_list));
	}

	public Ab_onClean_bA(fn: (list: Ab_Tile_bA[])=>void){
		this.Ab_clean_call_list_bA.push(fn);
	}
}

